package imp

import (
	sqlc "bgs/db/sqlc"
	syncGrpc "bgs/grpc/gen/service/sync"
	"bgs/grpc/gen/shared/message"
	"bgs/util"
	"context"
	"database/sql"
)

/****************************************************************************************/
/*                               sync_mapping entity of helper                          */
/****************************************************************************************/

func transformSyncMappingEntityToPb(mapping sqlc.SyncMapping) *syncGrpc.SyncMappingEntity {
	return &syncGrpc.SyncMappingEntity{
		Id:        mapping.ID,
		SyncId:    mapping.SyncID,
		LocalObj:  mapping.LocalObj,
		LocalPk:   mapping.LocalPk,
		RemoteObj: mapping.RemoteObj,
		RemotePk:  mapping.RemotePk,
	}
}

func mapSyncMappingEntityToPb(list []sqlc.SyncMapping, f func(sqlc.SyncMapping) *syncGrpc.SyncMappingEntity) []*syncGrpc.SyncMappingEntity {
	r := make([]*syncGrpc.SyncMappingEntity, len(list))
	for i, item := range list {
		r[i] = f(item)
	}
	return r
}

/****************************************************************************************/
/*                               sync_mapping entity of query                           */
/****************************************************************************************/

// GetSyncMappingByLocalObjAndLocalPk 获取单个同步映射
func (s *SyncAPIService) GetSyncMappingByLocalObjAndLocalPk(ctx context.Context, req *syncGrpc.GetSyncMappingByLocalObjAndLocalPkRequest) (res *syncGrpc.GetSyncMappingByLocalObjAndLocalPkResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("syncImp->GetSyncMappingByLocalObjAndLocalPk:%v", req)
	res = &syncGrpc.GetSyncMappingByLocalObjAndLocalPkResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	arg := sqlc.GetSyncMappingByLocalObjAndLocalPkParams{
		LocalObj: req.LocalObj,
		LocalPk:  req.LocalPk,
	}
	syncMapping, sqlErr := s.dao.Q.GetSyncMappingByLocalObjAndLocalPk(ctx, arg)
	if sqlErr != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    util.Int32IfThenElse(sql.ErrNoRows == sqlErr, 404, 400),
			Msg:     sqlErr.Error(),
		}
		return
	}
	res.SyncMapping = transformSyncMappingEntityToPb(syncMapping)
	return
}

// ListSyncMappingsBySyncID 分页获取多个同步映射
func (s *SyncAPIService) ListSyncMappingsBySyncID(ctx context.Context, req *syncGrpc.ListSyncMappingsBySyncIDRequest) (res *syncGrpc.ListSyncMappingsBySyncIDResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("sync_mappingImp->ListSyncMappingsBySyncID:%v", req)
	res = &syncGrpc.ListSyncMappingsBySyncIDResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	total, err := s.dao.Q.CountSyncMappingsBySyncID(ctx, req.SyncId)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}

	if total == 0 {
		// 不用继续调用listfunc
		return
	}

	arg := sqlc.ListSyncMappingsBySyncIDParams{
		Limit:  req.Limit,
		Offset: req.Offset,
		SyncID: req.SyncId,
	}
	syncMappings, err := s.dao.Q.ListSyncMappingsBySyncID(ctx, arg)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.Total = total
	res.SyncMappings = mapSyncMappingEntityToPb(syncMappings, transformSyncMappingEntityToPb)
	return
}
